package cn.blackhole.simple.domain.Metric.service.impl;

import cn.blackhole.simple.common.enums.InterfaceType;
import cn.blackhole.simple.domain.Metric.model.entity.ExceptionStat;
import cn.blackhole.simple.domain.Metric.model.entity.MetricData;
import cn.blackhole.simple.domain.Metric.model.objValue.MetricType;
import cn.blackhole.simple.domain.Metric.service.MetricsCollector;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

public class DefaultMetricsCollector implements MetricsCollector {
    private final ConcurrentMap<InterfaceType, ConcurrentMap<MetricType, AtomicLong>> counters
            = new ConcurrentHashMap<>();

    private final ConcurrentMap<Class<? extends Throwable>, AtomicInteger> exceptionStats
            = new ConcurrentHashMap<>();

    private final Histogram responseTimeHistogram = new Histogram();

    @Override
    public void recordMetric(MetricData data) {
        counters.computeIfAbsent(data.getInterfaceType(), k -> new ConcurrentHashMap<>())
                .computeIfAbsent(data.getMetricType(), k -> new AtomicLong())
                .addAndGet((long) data.getValue());

        if (data.getMetricType() == MetricType.RESPONSE_TIME) {
            responseTimeHistogram.record((long) data.getValue());
        }
    }

    @Override
    public void recordException(InterfaceType type, Throwable ex) {
        exceptionStats.computeIfAbsent(ex.getClass(), k -> new AtomicInteger()).incrementAndGet();
        MetricsCollector.super.recordException(type, ex);
    }

    @Override
    public Map<InterfaceType, Map<MetricType, Double>> getMetrics() {
        // 转换计数器数据到返回结构
        return null;
    }

    @Override
    public List<ExceptionStat> getExceptionStats() {
        // 转换异常统计数据
        return null;
    }

    // 直方图实现（可替换为HdrHistogram）
    private static class Histogram {
        private final LongAdder sum = new LongAdder();
        private final LongAdder count = new LongAdder();
        private final TreeMap<Long, Long> buckets = new TreeMap<>();

        synchronized void record(long value) {
            sum.add(value);
            count.increment();
            long bucket = value / 100 * 100; // 按100ms分桶
            buckets.put(bucket, buckets.getOrDefault(bucket, 0L) + 1);
        }
    }
}